package com.ledi.guns.modular.ledipay.service.impl;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayEcoEduKtBillingModifyRequest;
import com.alipay.api.request.AlipayEcoEduKtBillingQueryRequest;
import com.alipay.api.request.AlipayEcoEduKtBillingSendRequest;
import com.alipay.api.request.AlipayEcoEduKtSchoolinfoModifyRequest;
import com.alipay.api.request.AlipayOpenAuthTokenAppRequest;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipayEcoEduKtBillingModifyResponse;
import com.alipay.api.response.AlipayEcoEduKtBillingQueryResponse;
import com.alipay.api.response.AlipayEcoEduKtBillingSendResponse;
import com.alipay.api.response.AlipayEcoEduKtSchoolinfoModifyResponse;
import com.alipay.api.response.AlipayOpenAuthTokenAppResponse;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.ledi.guns.common.exception.AppCheckException;
import com.ledi.guns.common.persistence.dao.BillAlipayMapper;
import com.ledi.guns.common.persistence.dao.BillDetailMapper;
import com.ledi.guns.common.persistence.dao.BillItemMapper;
import com.ledi.guns.common.persistence.dao.BillMapper;
import com.ledi.guns.common.persistence.dao.ClassInfoMapper;
import com.ledi.guns.common.persistence.dao.GradeMapper;
import com.ledi.guns.common.persistence.dao.RegionMapper;
import com.ledi.guns.common.persistence.dao.SchoolInfoMapper;
import com.ledi.guns.common.persistence.dao.SchoolPayItemMapper;
import com.ledi.guns.common.persistence.model.Bill;
import com.ledi.guns.common.persistence.model.BillAlipay;
import com.ledi.guns.common.persistence.model.BillDetail;
import com.ledi.guns.common.persistence.model.BillItem;
import com.ledi.guns.common.persistence.model.ClassInfo;
import com.ledi.guns.common.persistence.model.Grade;
import com.ledi.guns.common.persistence.model.SchoolInfo;
import com.ledi.guns.common.persistence.model.SchoolPayItem;
import com.ledi.guns.core.util.DateUtil;
import com.ledi.guns.core.util.SystemConstans;
import com.ledi.guns.modular.ledipay.service.EduPayObserver;

/**
 * 文件名称： com.ledi.guns.modular.ledipay.service.impl.EduPayAliObserver.java<br/>
 * 初始作者： 周登文<br/>
 * 创建日期： 2017年11月30日<br/>
 * 功能说明：支付宝缴费接口实现类 <br/>
 * =================================================<br/>
 * 修改记录：<br/>
 * 修改作者 日期 修改内容<br/>
 * ================================================<br/>
 * Copyright (橘子股份-幼儿事业部) 2012-2017.All rights reserved.<br/>
 */
@Service
public class EduPayAliObserver implements EduPayObserver {

	private static Logger logger = LoggerFactory.getLogger(EduPayAliObserver.class);
	private static String INVOKE_ALIPAY_API_FAILED_CODE = "invoke_alipay_api_failed";
	private DecimalFormat df = new DecimalFormat("######0.00");
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	/**
	 * K12同步账单状态：1:缴费成功，
	 */
	public final static String SYNC_STATUS_PAY_SUCCESS = "1";
	/**
	 * K12同步账单状态：2:关闭账单，
	 */
	public final static String SYNC_STATUS_CLOSE = "2";
	/**
	 * K12同步账单状态：3、退费
	 */
	public final static String SYNC_STATUS_REFUND = "3";

	@Value("${ali.apiUrl}")
	private String apiUrl;

	@Value("${ali.appid}")
	private String appid;

	@Value("${ali.priKey}")
	private String priKey;

	@Value("${ali.pubKey}")
	private String pubKey;

	@Value("${ali.notifyUrl}")
	private String notifyUrl;

	@Value("${ali.isvPid}")
	private String isvPid;

	@Value("${ali.isvName}")
	private String isvName;

	@Value("${ali.isvPhone}")
	private String isvPhone;

	private AlipayClient alipayClient;
	@Autowired
	private RegionMapper regionMapper;
	@Autowired
	BillStreamServiceImpl streamService;
	@Autowired
	BillDetailMapper billDetailMapper;
	@Autowired
	BillAlipayMapper billAlipayMapper;
	@Autowired
	BillMapper billMapper;
	@Autowired
	SchoolInfoMapper schoolInfoMapper;
	@Autowired
	BillItemMapper billItemMapper;
	@Autowired
	ClassInfoMapper classInfoMapper;
	@Autowired
	private SchoolPayItemMapper schoolPayItemMapper;
	@Autowired
	private GradeMapper gradeMapper;

	@Override
	public boolean sendBill(Long billId) {

		Bill bill = billMapper.selectById(billId);
		List<BillDetail> billDetailList = queryBillDetail(billId);
		SchoolInfo school = schoolInfoMapper.selectById(bill.getSchoolId());
		ArrayList<Future<BillDetail>> results = new ArrayList<Future<BillDetail>>();
		// ExecutorService exec = Executors.newFixedThreadPool(20);
		ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("thread-call-sendBill-%d").build();
		ExecutorService exec = new ThreadPoolExecutor(20, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), namedThreadFactory);

		for (BillDetail detail : billDetailList) {
			try {
				Callable<BillDetail> task = new Callable<BillDetail>() {

					@Override
					public BillDetail call() throws Exception {

						return sendBillDetail(bill, detail, school, 0);
					}
				};
				results.add(exec.submit(task));
			} catch (Exception e) {
				logger.error("[" + detail.getBillDetailId() + "]" + e.getMessage(), e);
			}
		}
		// 处理需要重试的账单
		for (Future<BillDetail> future : results) {
			try {
				BillDetail detail = future.get();
				if (detail != null) {
					try {
						logger.info("重试；billDetailId=" + detail.getBillDetailId());
						sendBillDetail(bill, detail, school, 1);
					} catch (Exception e) {
						logger.error("[" + detail.getBillDetailId() + "]" + e.getMessage(), e);
					}
				}
			} catch (InterruptedException | ExecutionException e1) {
				logger.error(e1.getMessage(), e1);
			}
		}
		return true;
	}

	/**
	 * 方法描述: [异步发送账单明细.]<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年12月6日-下午1:25:54<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @param bill
	 * @param detail
	 * @param school
	 *            void
	 */
	public BillDetail sendBillDetail(Bill bill, BillDetail detail, SchoolInfo school, int returyCount) {

		AlipayEcoEduKtBillingSendRequest request = new AlipayEcoEduKtBillingSendRequest();
		String reqData = "";
		String resData = "";
		try {
			detail.setPayWay(SystemConstans.PAY_WAY_ALI);
			String bizContent = constructAliSendBillBizContent(school, detail, bill);
			request.setBizContent(bizContent);
			reqData = request.getBizContent();
			logger.info("向支付宝发送账单：[" + detail.getBillDetailId() + "]");
			logger.info("req info[" + detail.getBillDetailId() + "]:" + request.getBizContent());
			AlipayEcoEduKtBillingSendResponse response = getAliPayClient().execute(request);
			logger.info("res info[" + detail.getBillDetailId() + "]:" + response.getBody());
			resData = response.getBody();

			if (response.isSuccess()) {
				detail.setBillStatus(SystemConstans.BILL_STATUS_SEND_SUCCESS);
				detail.setBillDetailBeginTime(new Date());
				BillAlipay billali = constructBillAliPay(response.getOrderNo(), response.getStudentNo(),
						school.getAlipayPid(), detail.getBillDetailId(),
						bill.getBillEndTime());
				billAlipayMapper.insert(billali);
			} else if ("isp.unknow-erro".equals(response.getSubCode())
					|| "aop.unknow-error".equals(response.getSubCode())) {
				// isp.unknow-error 服务暂不可用（业务系统不可用） 稍后重试
				// aop.unknow-error 服务暂不可用（网关自身的未知错误） 稍后重试
				if (returyCount == 1) {
					// 重试后，仍不成功，记为失败
					detail.setBillStatus(SystemConstans.BILL_STATUS_SEND_FAIL);
					detail.setFileReason(response.getSubMsg());
				}
			} else {
				detail.setBillStatus(SystemConstans.BILL_STATUS_SEND_FAIL);
				detail.setFileReason(response.getSubMsg());
			}
		} catch (AlipayApiException e) {
			logger.error("[" + detail.getBillDetailId() + "]" + e.getMessage(), e);
			if (returyCount == 1) {
				// 重试后，仍不成功，记为失败
				detail.setBillStatus(SystemConstans.BILL_STATUS_SEND_FAIL);
				if (e.getMessage() != null && e.getMessage().indexOf("timed out") != -1) {
					detail.setFileReason("支付宝服务器繁忙，请重试。");
				} else {
					detail.setFileReason(e.getMessage());
				}
			}
		} catch (Exception e) {
			logger.error("[" + detail.getBillDetailId() + "]" + e.getMessage(), e);
			detail.setBillStatus(SystemConstans.BILL_STATUS_SEND_FAIL);
			detail.setFileReason("未知");
		}
		streamService.billStream("发送账单", detail.getBillDetailId(), SystemConstans.API_INVOKE_TYPE_SEND,
				SystemConstans.PAY_WAY_ALI, reqData, resData);
		if (detail.getBillStatus() != SystemConstans.BILL_STATUS_UNSEND) {
			billDetailMapper.updateById(detail);
			return null;
		} else {
			return detail;
		}

	}

	/**
	 * 方法描述: [生成发送账单的请求报文.]<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年12月2日-下午2:00:12<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @param school
	 * @param detail
	 * @param bill
	 * @return String
	 */
	private String constructAliSendBillBizContent(SchoolInfo school, BillDetail detail, Bill bill) {

		ClassInfo classinfo = classInfoMapper.selectById(detail.getClassId());

		Integer billType = bill.getBillType();
		JSONObject biz = new JSONObject();

		// 带收费项
		if (billType != null && billType > SystemConstans.NO) {

			biz.put("school_pid", school.getAlipayPid());
			biz.put("school_no", school.getSchoolNo());
			biz.put("child_name", detail.getStudentName());
			String className = "";
			if (classinfo.getGradeId() != null) {
				Grade selectById = gradeMapper.selectById(classinfo.getGradeId());
				className = selectById.getName() + classinfo.getOrderNum() + "班";
			}
			biz.put("class_in", StringUtils.isNotBlank(classinfo.getName()) ? classinfo.getName() : className);
			biz.put("out_trade_no", detail.getBillDetailId());
			biz.put("charge_bill_title", bill.getName());
			// biz.put("amount", df.format(detail.getTotalDetail()));
			biz.put("gmt_end", sdf.format(bill.getBillEndTime()));
			biz.put("end_enable", "Y");
			biz.put("charge_type", "M"); // 缴费项模式：空或"N"，表示缴费项不可选， "M"表示缴费项为可选 ，支持单选和多选。
			biz.put("partner_id", isvPid);
			// 用户信息
			JSONObject user = new JSONObject();
			user.put("user_mobile", detail.getParentMobile());
			JSONArray users = new JSONArray();
			users.add(user);
			biz.put("users", users);
			// 收费项目
			List<SchoolPayItem> schoolPayItems = schoolPayItemMapper.selectByBillId(bill.getId(), school.getId());
			JSONArray items = new JSONArray();
			if (CollectionUtils.isNotEmpty(schoolPayItems)) {
				BigDecimal amount = new BigDecimal(0);
				for (int i = 0; i < schoolPayItems.size(); i++) {
					JSONObject item = new JSONObject();
					item.put("item_name", schoolPayItems.get(i).getName());
					item.put("item_serial_number", i + 1);
					BigDecimal money = schoolPayItems.get(i).getMoney();
					// 必选
					Integer flag = schoolPayItems.get(i).getFlag();
					if (flag > 0) {
						item.put("item_mandatory", "Y");
					} else {
						item.put("item_mandatory", "N");
					}
					if (flag == SystemConstans.TWO)
					{
						money = money.negate();
					}
					amount = amount.add(money);
					item.put("item_price", df.format(money));
					item.put("item_maximum", 1);
					items.add(item);
				}
				biz.put("amount", df.format(amount));

			} else {
				throw new AppCheckException("school.schoolPayItem.bill.noExit.code", "school.schoolPayItem.bill.noExit.message", bill.getId());
			}
			biz.put("charge_item", items);

		} else {
			// 不带收费项
			biz.put("school_pid", school.getAlipayPid());
			biz.put("school_no", school.getSchoolNo());
			biz.put("child_name", detail.getStudentName());
			biz.put("class_in", classinfo.getName());
			biz.put("out_trade_no", detail.getBillDetailId());
			biz.put("charge_bill_title", bill.getName());
			biz.put("amount", df.format(detail.getTotalDetail()));
			biz.put("gmt_end", sdf.format(bill.getBillEndTime()));
			biz.put("end_enable", "Y");
			biz.put("partner_id", isvPid);
			// 用户信息
			JSONObject user = new JSONObject();
			user.put("user_mobile", detail.getParentMobile());
			JSONArray users = new JSONArray();
			users.add(user);
			biz.put("users", users);
			// 收费项目
			Map<String, Object> queryBillItemCondition = new HashMap<String, Object>();
			queryBillItemCondition.put("billl_detail_id", detail.getBillDetailId());
			List<BillItem> itemList = billItemMapper.selectByMap(queryBillItemCondition);
			JSONArray items = new JSONArray();
			for (BillItem billItem : itemList) {
				JSONObject item = new JSONObject();
				item.put("item_name", billItem.getItemName());
				item.put("item_price", df.format(billItem.getItemMoney()));
				items.add(item);
			}
			biz.put("charge_item", items);

		}
		return biz.toJSONString();
	}

	/**
	 * 方法描述: [生成支付宝家长付款记录]<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年12月2日-下午2:00:58<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @param aliOrderNo
	 * @param aliStudentNo
	 * @param schoolPid
	 * @param billDetailId
	 * @return BillAlipay
	 */
	private BillAlipay constructBillAliPay(String aliOrderNo, String aliStudentNo, String schoolPid,
			String billDetailId, Date billEndTime) {

		BillAlipay billali = new BillAlipay();
		billali.setAlipayOrderNo(aliOrderNo);
		billali.setAlipayStudentNo(aliStudentNo);
		billali.setBillStatus(SystemConstans.BILL_STATUS_SEND_SUCCESS);
		billali.setBillDetailId(billDetailId);
		billali.setCreateTime(new Date());
		billali.setSchoolPid(schoolPid);
		billali.setCreateTime(new Date());
		billali.setBillEndTime(billEndTime);
		return billali;
	}

	/**
	 * 方法描述: [根据账单ID查询账单明细列表.]<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年12月4日-上午10:25:22<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @param billId
	 * @return List<BillDetail>
	 */
	private List<BillDetail> queryBillDetail(Long billId) {

		Map<String, Object> queryBillDetailCondition = new HashMap<String, Object>();
		queryBillDetailCondition.put("bill_id", billId);
		queryBillDetailCondition.put("is_delete", SystemConstans.NO);
		queryBillDetailCondition.put("bill_status", SystemConstans.BILL_STATUS_UNSEND);
		return billDetailMapper.selectByMap(queryBillDetailCondition);
	}

	/**
	 * 方法描述:录入学校信息<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年11月30日-下午5:45:32<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @return 支付宝端的学校编号
	 */
	@Override
	public String addSchool(SchoolInfo school) {

		String provinceName = regionMapper.getNameByCode(school.getProvinceCode());
		String cityName = regionMapper.getNameByCode(school.getCityCode());
		String districtName = regionMapper.getNameByCode(school.getDistrictCode());
		AlipayEcoEduKtSchoolinfoModifyRequest request = new AlipayEcoEduKtSchoolinfoModifyRequest();
		JSONObject biz = new JSONObject();
		biz.put("school_name", school.getSchoolName());
		biz.put("school_type", school.getSchoolType());
		biz.put("province_name", provinceName);
		biz.put("province_code", school.getProvinceCode());
		biz.put("city_name", cityName);
		biz.put("city_code", school.getCityCode());
		biz.put("district_name", districtName);
		biz.put("district_code", school.getDistrictCode());
		biz.put("isv_name", isvName);
		biz.put("isv_notify_url", notifyUrl);
		biz.put("isv_pid", isvPid);
		biz.put("isv_phone", isvPhone);
		biz.put("school_pid", school.getAlipayPid());
		request.setBizContent(biz.toJSONString());
		try {
			logger.info("录入学校信息：");
			logger.info("req info:" + request.getBizContent());
			AlipayEcoEduKtSchoolinfoModifyResponse response = getAliPayClient().execute(request);
			logger.info("res info:" + response.getBody());
			if (response.isSuccess() && "Y".equals(response.getStatus())) {
				return response.getSchoolNo();
			} else {
				throw new AppCheckException(INVOKE_ALIPAY_API_FAILED_CODE, response.getSubMsg());
			}
		} catch (AlipayApiException e) {
			logger.error(e.getMessage(), e);
			throw new AppCheckException(INVOKE_ALIPAY_API_FAILED_CODE, e.getMessage());
		}

	}

	/**
	 * 方法描述:根据支付宝返回的授权码获取学样的Pid[学校向商户授权]<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年12月1日-上午11:00:13<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @param app_auth_code
	 *            支付宝返回的授权码
	 * @return String 学样的Pid
	 */
	@Deprecated
	public String openAuthToken(String app_auth_code) {

		AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
		JSONObject biz = new JSONObject();
		biz.put("grant_type", "authorization_code");
		biz.put("code", app_auth_code);
		request.setBizContent(biz.toJSONString());
		logger.info("根据支付宝返回的授权码获取学样的Pid：");
		logger.info("req info:" + request.getBizContent());
		try {
			AlipayOpenAuthTokenAppResponse response = getAliPayClient().execute(request);
			logger.info("res info:" + response.getBody());
			if (response.isSuccess()) {
				return response.getUserId();
			} else {
				throw new AppCheckException(INVOKE_ALIPAY_API_FAILED_CODE, response.getMsg());
			}
		} catch (AlipayApiException e) {
			throw new AppCheckException(INVOKE_ALIPAY_API_FAILED_CODE, e.getMessage());
		}

	}

	/**
	 * 方法描述:根据支付宝返回的授权码获取学样的Pid[支付宝用户登录授权]<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年12月1日-上午11:00:13<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @param auth_code
	 *            支付宝返回的授权码
	 * @return String 学样的Pid
	 */
	public String loginAuthToken(String auth_code) {

		AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
		request.setCode(auth_code);
		request.setGrantType("authorization_code");
		logger.info("根据支付宝返回的授权码获取学样的Pid：");
		logger.info("req info:auth_code=" + request.getCode());
		try {
			AlipaySystemOauthTokenResponse response = getAliPayClient().execute(request);
			logger.info("res info:" + response.getBody());
			if (response.isSuccess()) {
				return response.getUserId();
			} else {
				throw new AppCheckException(INVOKE_ALIPAY_API_FAILED_CODE, response.getSubMsg());
			}
		} catch (AlipayApiException e) {
			throw new AppCheckException(INVOKE_ALIPAY_API_FAILED_CODE, e.getMessage());
		}
	}

	/**
	 * 查询账单是否支付成功 方法描述: [这里用一句话描述这个方法的作用.]<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年12月5日-下午5:00:03<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @param schoolPid
	 *            学校的支付宝PID
	 * @param ali_order_no
	 *            ISV调用发送账单接口，返回给商户的order_no
	 * @return boolean
	 */
	public boolean havePay(
			BillAlipay billAlipay, String schoolPid, String ali_order_no) {

		AlipayEcoEduKtBillingQueryRequest request = new AlipayEcoEduKtBillingQueryRequest();
		JSONObject biz = new JSONObject();
		biz.put("isv_pid", isvPid);
		biz.put("school_pid", schoolPid);
		biz.put("out_trade_no", ali_order_no);
		request.setBizContent(biz.toJSONString());
		try {
			logger.info("查询账单状态：");
			logger.info("req info:" + request.getBizContent());
			AlipayEcoEduKtBillingQueryResponse response = getAliPayClient().execute(request);
			logger.info("res info:" + response.getBody());
			if (response.isSuccess()) {
				if ("PAY_SUCCESS".equals(response.getOrderStatus())
						|| "BILLING_SUCCESS".equals(response.getOrderStatus())) {
					int billStatus = SystemConstans.BILL_STATUS_PAY_SUCCESS;
					billAlipay.setBillStatus(billStatus);
					billAlipay.setComment("扭转账单状态成功，" + DateUtil.getTime());
					billAlipayMapper.updateById(billAlipay);
					updateBillStatus(billAlipay.getBillDetailId(), billStatus,
							SystemConstans.PAY_WAY_ALI);
					logger.info("关闭过期未支付账单，billDetailId=" + billAlipay.getBillDetailId());

					return true;
				} else {
					if ("TIMEOUT_CLOSED".equals(response.getOrderStatus()) || "ISV_CLOSED".equals(response.getOrderStatus())
							|| billAlipay.getBillEndTime().getTime() <= System.currentTimeMillis()) {
						int billStatus = SystemConstans.BILL_STATUS_CANCEL;
						billAlipay.setBillStatus(billStatus);
						billAlipay.setComment("过期未支付，账单关闭，" + DateUtil.getTime());
						billAlipayMapper.updateById(billAlipay);
						updateBillStatus(billAlipay.getBillDetailId(), billStatus,
								SystemConstans.PAY_WAY_ALI);
						logger.info("关闭过期未支付账单，billDetailId=" + billAlipay.getBillDetailId());
					}
				}
			}
		} catch (AlipayApiException e) {
			logger.error(e.getMessage(), e);
		}
		return false;
	}

	/**
	 * 方法描述: [同步账单状态.]<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年12月8日-下午4:20:00<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @param ali_order_no
	 *            ISV调用发送账单接口，返回给商户的order_no
	 * @param status
	 *            状态：1:缴费成功，2:关闭账单，3、退费
	 * @return boolean
	 */
	public boolean syncStatus(String ali_order_no, String status, String billDetailId) {

		AlipayEcoEduKtBillingModifyRequest request = new AlipayEcoEduKtBillingModifyRequest();
		JSONObject biz = new JSONObject();
		biz.put("out_trade_no", ali_order_no);
		biz.put("status", status);
		request.setBizContent(biz.toString());
		AlipayEcoEduKtBillingModifyResponse response = null;
		boolean result = false;
		try {
			logger.info("同步账单状态：");
			logger.info("req info:" + request.getBizContent());
			response = getAliPayClient().execute(request);
			logger.info("res info:" + response.getBody());
			if (response.isSuccess()) {
				result = "Y".equals(response.getStatus());
			} else {
				throw new AppCheckException(INVOKE_ALIPAY_API_FAILED_CODE, response.getSubMsg());
			}
		} catch (AlipayApiException e) {
			throw new AppCheckException(INVOKE_ALIPAY_API_FAILED_CODE, response.getMsg());
		} finally {
			streamService.billStream("同步账单状态", billDetailId, SystemConstans.API_INVOKE_TYPE_SEND,
					SystemConstans.PAY_WAY_ALI, request.getBizContent(),
					response == null ? "" : response.getBody());
		}

		return result;
	}

	/**
	 * 方法描述: [查询支付宝订单状态.]<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2018年5月24日-下午7:06:01<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * 
	 * @param schoolPid
	 * @param ali_order_no
	 * @return
	 *         NOT_PAY 待缴费
	 *         PAYING 支付中
	 *         PAY_SUCCESS 支付成功，处理中
	 *         BILLING_SUCCESS 缴费成功
	 *         TIMEOUT_CLOSED 逾期关闭账单
	 *         ISV_CLOSED 账单关闭
	 */
	public String queryStatus(String schoolPid, String ali_order_no) {

		AlipayEcoEduKtBillingQueryRequest request = new AlipayEcoEduKtBillingQueryRequest();
		JSONObject biz = new JSONObject();
		biz.put("isv_pid", isvPid);
		biz.put("school_pid", schoolPid);
		biz.put("out_trade_no", ali_order_no);
		request.setBizContent(biz.toJSONString());
		try {
			logger.info("查询账单状态：");
			logger.info("req info:" + request.getBizContent());
			AlipayEcoEduKtBillingQueryResponse response = getAliPayClient().execute(request);
			logger.info("res info:" + response.getBody());
			if (response.isSuccess()) {
				return response.getOrderStatus();
			}
		} catch (AlipayApiException e) {
			logger.error(e.getMessage(), e);
		}
		return "";
	}

	/**
	 * 方法描述: 初始化支付宝接口调用类<br/>
	 * 初始作者: 周登文<br/>
	 * 创建日期: 2017年11月30日-下午5:47:32<br/>
	 * 开始版本: 1.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 *
	 * @return AlipayClient
	 */
	private AlipayClient getAliPayClient() {

		if (alipayClient == null) {
			alipayClient = new DefaultAlipayClient(apiUrl, appid, priKey, AlipayConstants.FORMAT_JSON,
					AlipayConstants.CHARSET_UTF8, pubKey,
					AlipayConstants.SIGN_TYPE_RSA2);
		}
		return alipayClient;
	}

	public void updateBillStatus(String billDetailId, int payStatus, String payWay) {

		BillDetail billDetail = new BillDetail();
		billDetail.setBillDetailId(billDetailId);
		billDetail = billDetailMapper.selectOne(billDetail);
		billDetail.setPayTime(new Date());
		billDetail.setPayWay(payWay);
		billDetail.setBillStatus(payStatus);
		billDetailMapper.updateById(billDetail);
	}

}
